• Jump To … +
    main.js separate.js single.js web-apg-api.js main.js web-conv-api.js ast.js csv.js dangling-else.js display.js flags.js float.js limits.js main.js multiline-mode.js recursive.js replace.js rules.js split.js testonly.js trace.js udt.js unicode.js web-email.js word-boundaries.js main.js phone-number.js web-main.js web-phone-number.js main.js phone-number.js setup.js translate.js xml.js branch-fail-grammar.js main.js parent-mode-grammar.js setup.js universal-mode-grammar.js colors-app.js colors-callbacks.js colors.js main.js more-app.js more-setup.js more.js ast-callbacks.js bad-input.js basic.js ini-file.js main.js parser-callbacks.js setup.js trace.js anbncn.js and.js c-comment.js compound.js main.js nested.js not.js setup.js boundaries-grammar.js boundaries.js comment-grammar.js comment.js main.js negative-grammar.js negative.js positive-grammar.js positive.js setup.js main.js odata-grammar.js run.js setup.js area-code.js lookaround.js main.js phone-number.js setup.js simple.js all-operators.js default.js fancy-number.js limited-lines.js main.js select-operators.js select-rules.js setup.js main.js minimal.js parent-u.js parent.js phone-number.js setup.js stats.js trace.js universal-u.js universal.js callbacks.js grammar.js main.js parser.js writeHtml.js LICENSE.md README.md index.md
  • colors-app.js

  • §
    /* eslint-disable new-cap */
    /*  *************************************************************************************
     *   copyright: Copyright (c) 2021 Lowell D. Thomas, all rights reserved
     *     license: BSD-2-Clause (https://opensource.org/licenses/BSD-2-Clause)
     *   ********************************************************************************* */
  • §

    This example demonstrates how to call a UDT from a rule name callback function. This is something you will probably never need to do and you might want to just skip over this example. Using this feature changes the grammar that the parser will recognize in unpredictable ways, unless you really, really know what you are doing and exactly how the UDT you are calling works. The only reason these examples are here, is to verify that the evaluateRule() and evaluateUdt() functions are working. And the only reason this feature exists at all is because there was a case at one time where I really wanted to use a UDT but I also really wanted some rule name nodes below it on the AST for easy translation. For completeness, evaluateRule() was added along with evaluateUdt().

    There are actually three demonstrations here.

    • the first and most common case is that the syntax callback functions just monitor the parsing process without altering it. This might include looking for specific rules designed to locate errors, or tabulating data, or some other administrative activity.
    • in the second demonstration, the callback function actually alters the flow of the parser. In this case, it simply causes the parser to fail no matter what the input string is, correct or not. A more realistic use of this might be to examine two alternatives, both of which are correct syntactically, but reject one based on some type of semantic criteria.
    • in the third demonstration, the syntax callback alters the parsing process by ignoring the prescribed grammar altogether and matching phrases with available UDT functions.

    All three demonstrations are done and the traces of them displayed on a single web page for comparison of how the parser actually performed. For the basics of setting up and executing the parser see setup.js.

    (function colorsApp() {
      const nodeUtil = require('node:util');
      const inspectOptions = {
        showHidden: true,
        depth: null,
      };
      try {
        let result;
        let inputString;
        let inputCharacterCodes;
        let html;
        const { apgLib } = require('apg-js');
        const grammar = new (require('./colors'))();
        const callbacks = require('./colors-callbacks');
        const writeHtml = require('../writeHtml');
        const fileName = 'colors-app';
        const parser = new apgLib.parser();
    
        /* set up the parser */
        parser.trace = new apgLib.trace();
        inputString = 'red,white,blue';
        inputCharacterCodes = apgLib.utils.stringToChars(inputString);
        const startRule = 0;
    
        /* define the callback fuctions for demo one */
        parser.callbacks.start = callbacks.startCallback;
        parser.callbacks.u_blue = callbacks.u_blueCallback;
        parser.callbacks.u_red = callbacks.u_redCallback;
        parser.callbacks.u_white = callbacks.u_whiteCallback;
        parser.callbacks.u_yellow = callbacks.u_yellowCallback;
  • §

    In this case, the color callback function just monitors the parser’s flow without altering it. The input string is parsed and the trace saved for later display on a web page. (See colors-callbacks.js for the callback functions.)

        const data = [];
        parser.callbacks.color = callbacks.monitorCallback;
        result = parser.parse(grammar, startRule, inputCharacterCodes, data);
        console.log();
        console.log('the monitor callback results');
        console.dir(result, inspectOptions);
        html = parser.trace.toHtml(null, 'monitor callback');
  • §

    In this case, the color callback function actually modifies the parsing process by returning a non-ACTIVE state. The action in this case is to always fail, which is simply to demonstrate how modification from a syntax callback function can be done.

        parser.callbacks.color = callbacks.modifyCallback;
        result = parser.parse(grammar, startRule, inputCharacterCodes, data);
        console.log();
        console.log('the modify callback results');
        console.dir(result, inspectOptions);
        html += parser.trace.toHtml(null, 'modify callback');
  • §

    In this case the color callback function modifies the parsing process by calling a UDT function to do its work. In addition to accepting the colors red, white and blue, it uses a UDT to accept yellow as well.

        inputString = 'red,white,blue,yellow';
        inputCharacterCodes = apgLib.utils.stringToChars(inputString);
        parser.callbacks.color = callbacks.callUdtCallback;
        result = parser.parse(grammar, startRule, inputCharacterCodes, data);
        console.log();
        console.log('the evaluateUdt() callback results');
        console.dir(result, inspectOptions);
        html += parser.trace.toHtml('ascii', 'evaluateUdt() callback');
        html = apgLib.utils.htmlToPage(html, 'colors app');
        writeHtml(html, fileName);
      } catch (e) {
        let msg = '\nEXCEPTION THROWN: \n';
        if (e instanceof Error) {
          msg += `${e.name}: ${e.message}`;
        } else if (typeof e === 'string') {
          msg += e;
        } else {
          msg += nodeUtil.inspect(e, inspectOptions);
        }
        process.exitCode = 1;
        console.log(msg);
        throw e;
      }
    })();